Strict

Import agfx_extension

Class TImage

	Field name:String
	Field image:Image
	Field w:Int
	Field h:Int
	Field w2:Float
	Field h2:Float
	Field midhandled:Int=0


	' for tile maps
	Field tileWidth:Int, tileHeight:Int
	Field tileCountX:Int, tileCountY:Int
	Field tileCount:Int
	Field tileSpacing:Int, tileMargin:Int
	
	Method Load:Void(file$, midhandle:Bool=True)
		Self.name = StripAll(file.ToUpper())		
		Self.image = LoadBitmap(file)	
		Self.CalcSize()
		MidHandle(midhandle)
	End
	
	Method LoadAnim:Void(file$, w%, h%, total%, tmpImage:Image, midhandle:Bool=True)
		name = StripAll(file.ToUpper())
		image = LoadAnimBitmap(file, w, h, total, tmpImage)	
		CalcSize()
		MidHandle(midhandle)
	End
	
	Method GetPivotX:Int()
		Return Self.image.HandleX()
	End

	Method GetPivotY:Int()
		Return Self.image.HandleY()
	End

	Method CalcSize:Void()
		If image <> Null Then
			w = image.Width()
			h = image.Height()
			w2 = w/2
			h2 = h/2
		End
	End
	
	Method MidHandle:Void(midhandle:Bool) Property
		If midhandle Then
			image.SetHandle(w2, h2)
			Self.midhandled=1
		Else
			image.SetHandle(0, 0)
			Self.midhandled=0
		End 
	End
	
	Method MidHandle:Bool() Property
		Return Self.midhandled = 1
	End

	
	Method LoadTileset:Void(file:String, tileWidth:Int, tileHeight:Int, tileMargin:Int = 0, tileSpacing:Int = 0, midhandle:Bool=False)
		Load(file, midhandle)
		Self.tileWidth = tileWidth
		Self.tileHeight = tileHeight
		Self.tileMargin = tileMargin
		Self.tileSpacing = tileSpacing
		tileCountX = (w - tileMargin) / (tileWidth + tileSpacing)
		tileCountY = (h - tileMargin) / (tileHeight + tileSpacing)
		tileCount = tileCountX * tileCountY
	End


	Method Draw:Void(x#, y#, rotation# = 0, scaleX# = 1, scaleY# = 1, frame% = 0)
		DrawImage(Self.image, x, y, rotation, scaleX, scaleY, frame)
	End
	
	Method PreCache:Void()
		DrawImage Self.image, -Self.w-50, -Self.h-50
	End

	Method DrawSubImage:Void(destX:Float, destY:Float, srcX:Float, srcY:Float, srcWidth:Float, srcHeight:Float, rotation:Float = 0, scaleX:Float = 1, scaleY:Float = 1, frame:Int = 0)
		DrawImageRect(Self.image, destX, destY, srcX, srcY, srcWidth, srcHeight, rotation, scaleX, scaleY, frame)
	End
	
	Method DrawTile:Void(x:Float, y:Float, tile:Int = 0, rotation:Float = 0, scaleX:Float = 1, scaleY:Float = 1)
		Local srcX% = tileMargin + (tileWidth + tileSpacing) * (tile Mod tileCountX)
		Local srcY% = tileMargin + (tileHeight + tileSpacing) * (tile / tileCountX)
		DrawImageRect(Self.image, x, y, srcX, srcY, tileWidth, tileHeight, rotation, scaleX, scaleY)
	End
	
	Method DrawGrid:Void(x:Float, y:Float, rw:Float, rh:Float, frame:Int = 0)
		' draw top left corner
		DrawImageRect(self.image, x, y, 0, 0, leftMargin, topMargin, frame)
		' draw top right corner
		DrawImageRect(self.image, x+rw-rightMargin, y, w-rightMargin, 0, rightMargin, topMargin, frame)
		' draw bottom left corner
		DrawImageRect(self.image, x, y+rh-bottomMargin, 0, h-bottomMargin, leftMargin, bottomMargin, frame)
		' draw bottom right corner
		DrawImageRect(self.image, x+rw-rightMargin, y+rh-bottomMargin, w-rightMargin, h-bottomMargin, rightMargin, bottomMargin, frame)
		
		' work out how many horizontal and vertical tiles
		Local tileWidth% = (w-leftMargin-rightMargin)
		Local tileHeight% = (h-topMargin-bottomMargin)
		Local tileXCount% = (rw-leftMargin-rightMargin) / tileWidth
		Local tileYCount% = (rh-topMargin-bottomMargin) / tileHeight
		Local tileXOverflow% = (rw-leftMargin-rightMargin) Mod tileWidth
		Local tileYOverflow% = (rh-topMargin-bottomMargin) Mod tileHeight
		
		' tile top and bottom edges
		For Local i% = 0 Until tileXCount
			DrawImageRect(self.image, leftMargin+i*tileWidth,0,leftMargin,0,tileWidth,topMargin,frame)
			DrawImageRect(self.image, leftMargin+i*tileWidth,rh-bottomMargin,leftMargin,h-bottomMargin,tileWidth,bottomMargin,frame)
		Next
		If tileXOverflow > 0 Then
			DrawImageRect(self.image, leftMargin+tileXCount*tileWidth,0,leftMargin,0,tileXOverflow,topMargin,frame)
			DrawImageRect(self.image, leftMargin+tileXCount*tileWidth,rh-bottomMargin,leftMargin,h-bottomMargin,tileXOverflow,bottomMargin,frame)
		End
		
		' tile left and right edges
		For Local i% = 0 Until tileYCount
			DrawImageRect(self.image, 0, topMargin+i*tileHeight,0,topMargin,leftMargin,tileHeight,frame)
			DrawImageRect(self.image, rw-rightMargin,topMargin+i*tileHeight,w-rightMargin,topMargin,rightMargin,tileHeight,frame)
		Next
		If tileYOverflow > 0 Then
			DrawImageRect(self.image, 0, topMargin+tileYCount*tileHeight,0,topMargin,leftMargin,tileYOverflow,frame)
			DrawImageRect(self.image, rw-rightMargin,topMargin+tileYCount*tileHeight,w-rightMargin,topMargin,rightMargin,tileYOverflow,frame)
		End
		
		' tile centre
		' TODO
	End

	Method DrawSubStretched:Void(destX:Float, destY:Float, destWidth:Float, destHeight:Float, srcX:Int, srcY:Int, srcWidth:Int, srcHeight:Int,
			rotation:Float = 0)', scaleX:Float = 1, scaleY:Float = 1, frame:Int = 0)
		' scales for stretching
		Local stretchScaleX:Float = destWidth / srcWidth
		Local stretchScaleY:Float = destHeight / srcHeight
		DrawImageRect(Self.image, destX, destY, srcX, srcY, srcWidth, srcHeight, rotation, stretchScaleX, stretchScaleY)', frame)
	End
	
	' Yes, a crapload of parameters.  Thankfully most of them are optional, and this will usually only be called internally by the GUI.
	' TODO: apply scale to parameters
	Method DrawSubGrid:Void(x:Float, y:Float, width:Float, height:Float,
			srcX:Int, srcY:Int, srcWidth:Int, srcHeight:Int,
			leftMargin:Int, rightMargin:Int, topMargin:Int, bottomMargin:Int,
			'rotation:Float = 0, scaleX:Float = 1, scaleY:Float = 1,
			drawTopLeft:Bool = True, drawTop:Bool = True, drawTopRight:Bool = True,
			drawLeft:Bool = True, drawCenter:Bool = True, drawRight:Bool = True,
			drawBottomLeft:Bool = True, drawBottom:Bool = True, drawBottomRight:Bool = True)
		' draw the corners
		If drawTopLeft Then DrawImageRect(Self.image,
				x, y, srcX, srcY,
				leftMargin, topMargin)', rotation, scaleX, scaleY)
		If drawTopRight Then DrawImageRect(Self.image,
				x+width-rightMargin, y, srcX+srcWidth-rightMargin, srcY,
				rightMargin, topMargin)', rotation, scaleX, scaleY)
		If drawBottomLeft Then DrawImageRect(Self.image,
				x, y+height-bottomMargin, srcX, srcY+srcHeight-bottomMargin,
				leftMargin, bottomMargin)', rotation, scaleX, scaleY)
		If drawBottomRight Then DrawImageRect(Self.image,
				x+width-rightMargin, y+height-bottomMargin, srcX+srcWidth-rightMargin, srcY+srcHeight-bottomMargin,
				rightMargin, bottomMargin)', rotation, scaleX, scaleY)
		
		' scales for stretching
		Local stretchScaleX:Float = (width-leftMargin-rightMargin) / (srcWidth-leftMargin-rightMargin)
		Local stretchScaleY:Float = (height-topMargin-bottomMargin) / (srcHeight-topMargin-bottomMargin)
		
		' draw edges
		If drawLeft Then DrawImageRect(Self.image,
				x, y+topMargin, srcX, srcY+topMargin,
				leftMargin, srcHeight-topMargin-bottomMargin,
				0, 1, stretchScaleY)
		If drawRight Then DrawImageRect(Self.image,
				x+width-rightMargin, y+topMargin, srcX+srcWidth-rightMargin, srcY+topMargin,
				rightMargin, srcHeight-topMargin-bottomMargin,
				0, 1, stretchScaleY)
		If drawTop Then DrawImageRect(Self.image,
				x+leftMargin, y, srcX+leftMargin, srcY,
				srcWidth-leftMargin-rightMargin, topMargin,
				0, stretchScaleX, 1)
		If drawBottom Then DrawImageRect(Self.image,
				x+leftMargin, y+height-bottomMargin, srcX+leftMargin, srcY+srcHeight-bottomMargin,
				srcWidth-leftMargin-rightMargin, bottomMargin,
				0, stretchScaleX, 1)
		
		' draw center
		If drawCenter Then DrawImageRect(Self.image,
				x+leftMargin, y+topMargin, srcX+leftMargin, srcY+topMargin,
				srcWidth-leftMargin-rightMargin, srcHeight-topMargin-bottomMargin,
				0, stretchScaleX, stretchScaleY)
	End
	
	Method Free:Void()
		Self.image.Discard()
	End Method
	
End

